package cn.backflow.web;

import cn.backflow.data.pagination.PageRequest;
import cn.backflow.utils.JsonMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.MessageSource;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

import static cn.backflow.utils.Strings.isBlank;
import static cn.backflow.utils.Strings.toInt;

public abstract class BaseSpringController {

    private static int DEFAULT_PAGE_SIZE = 10;

    @Autowired
    protected MessageSource messageSource;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-M-d"), true));
    }

    public PageRequest pageRequest(HttpServletRequest request, String defaultSortColumns) {
        return pageRequest(request, defaultSortColumns, DEFAULT_PAGE_SIZE);
    }

    public PageRequest pageRequest(HttpServletRequest request, String defaultSortColumns, Integer defaultPageSize) {
        String sort = request.getParameter("sc");
        String numb = request.getParameter("pn");
        String size = request.getParameter("ps");

        if (defaultPageSize == null) {
            defaultPageSize = DEFAULT_PAGE_SIZE;
        }

        int pageSize = toInt(size, defaultPageSize);
        if (pageSize > 500) {
            pageSize = 500;
        }

        int pageNumber = toInt(numb, 1);
        if (isBlank(sort)) {
            sort = defaultSortColumns;
        }

        PageRequest pr = new PageRequest(pageSize, pageNumber, sort);
        return setParameters(pr, request);
    }

    private PageRequest setParameters(PageRequest pr, HttpServletRequest request) {
        for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
            String[] values = entry.getValue();
            String value = values[0].trim();
            if (value.isEmpty()) {
                continue;
            }
            if (values.length == 1) {
                pr.addFilter(entry.getKey(), value);
                continue;
            }
            List<String> list = new ArrayList<>();
            for (String s : values) {
                s = s.trim();
                if (s.isEmpty()) {
                    continue;
                }
                list.add(s);
            }
            pr.addFilter(entry.getKey(), list.toArray(new String[0]));
        }
        return pr.setRequestUri(request.getRequestURI());
    }

    /**
     * format binding error messages
     *
     * @param errors BindingResult
     */
    protected JsonMap filedErrors(BindingResult errors, JsonMap json) {
        // JsonMap child = json.success(false).child("errors");
        List<String> list = new ArrayList<>();

        errors.getAllErrors().forEach(e -> {
            if (e instanceof FieldError) {
                FieldError fe = (FieldError) e;
                list.add(messageSource.getMessage(e, Locale.SIMPLIFIED_CHINESE));
                return;
            }
            list.add(e.getDefaultMessage());
        });
        return json.put("errors", list).success(false);
    }
}
